package vip.wangwenhao.sso.config.security;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import vip.wangwenhao.autoconfigure.pojo.CustomAuthenticationToken;

import java.util.Collection;

public class CustomTokenAuthenticationProvider implements AuthenticationProvider {
    private static Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationProvider.class);

    @Autowired
    private TokenStore tokenStore;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String accessToken = authentication.getName();

        logger.info("CustomTokenAuthenticationProvider.class: authenticate() - tokenStore:" + tokenStore);
        logger.info("CustomTokenAuthenticationProvider.class: authenticate() - accessToken:" + accessToken);
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(accessToken);
        logger.info("CustomTokenAuthenticationProvider.class: authenticate() - readAccessToken:" + JSONObject.toJSONString(oAuth2AccessToken));
        OAuth2Authentication oAuth2Authentication = tokenStore.readAuthentication(accessToken);
        if (null == oAuth2Authentication) {
            throw new InvalidTokenException("invalid token");
        }
        Collection<? extends GrantedAuthority> authorities = oAuth2Authentication.getAuthorities();
        return new CustomAuthenticationToken(oAuth2Authentication, authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //将此处改为自己编写的MobileAuthenticationToken类，providerManager会遍历
//   	security config中注册的provider，根据此方法返回true或false来决定由哪个provider
//   	去校验请求过来的authentication。
        return CustomAuthenticationToken.class
                .isAssignableFrom(authentication);
    }

    public TokenStore getTokenStore() {
        return tokenStore;
    }

    public void setTokenStore(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }
}